#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"
#include "cs.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
//#include <iostream>
//#include <string>


void
on_button2_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
   gtk_main_quit();
}


void
on_button1_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{

}


void
on_button5_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
   int i;
  
   i= csserver(button);
}


void
on_button4_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{

}


void
on_button6_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{

}



/*This handler bails us out after 5 seconds */

static void alarm_handler (int signo)
{
    //exit (0);
    
}

/* Start of program execution */

int csserver(GtkWidget *button)
{
/* Define the variables we will be using. The contents of the
broadcast_packet variable are based on the contents of a
packet captured using a packet sniffer (wireshark). The data
is exactly 25 bytes in size. The response is usually 114~ bytes,
but we'll use a larger buffer just to play safe.
*/
    int sockfd;
    const int on = 1;
    struct sockaddr_in address;
    struct sockaddr preply_addr;
    int result;
    char *broadcast_packet = "\xFF\xFF\xFF\xFFTSource Engine Query\xFF";
    char response[300];
    int addr_len = sizeof(preply_addr);
    int recvlen;
    int check=0,i=0,j=0,k=0;
    
    char ip[20],map_type[20],server_name[20];
    int p,z;
/* Initialise the socket for sending out a broadcast.
SOCK_DGRAM indicates a datagram protocol, or UDP.
We would use SOCK_STREAM for TCP.
*/
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("10.0.255.255");
    address.sin_port = htons(27015);
/* Clarify that we really want to do a broadcast and that this isn't
a mistake. The socket system makes this necessary just in case
we're a program that takes an IP address at the command line and
the user fooled us into making a broadcast.
*/
    setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
/* Broadcast now. Any CS servers that receive this will reply
with a 114~ byte UDP packet.
*/
result = sendto (sockfd, (void *) broadcast_packet, 25, 0,
(struct sockaddr *) &address, sizeof(address));
/* Abort with an error message if the broadcast didn't work */
    if (result == -1) {
	perror ("cscan");
	exit(1);
    }
/* Setup the handler that will bail us out after the timeout */
    signal (SIGALRM, alarm_handler);
/* Tell the system to raise the ALRM signal after 5 seconds */
    alarm (10);
/* Loop continously listening for responses to the broadcast from
any servers on the local network. The ALRM signal at the end of
5 seconds will bail us out.
*/
//	cout<<"yesssssssss";
    for (;;)
    {
/* recvfrom is a blocking call for UDP data. We need to listen on the
same port that we broadcasted from, hence the "sockfd" from the
original broadcast. */
//recvlen = recvfrom (sockfd, response, sizeof (response),0,&preply_addr, (socklen_t*)&addr_len);
//cout<<recvlen<<" recvlen";
        if ((recvlen = recvfrom (sockfd, response, sizeof (response), 0,&preply_addr, (socklen_t*)&addr_len)) > 0)
	{ 
	//    printf("YESSSS\n");
/* We got a reply. This bit of code patches the packet contents
slightly to create printable text. Use a packet sniffer if you
want to see what the packet really contains. tcpdump won't work
here -- it loses the last few bytes. Try ethereal instead.
*/
	    response[recvlen-1] = '\0';
//	    string resp;
//	    resp=response;
   	//    resp.erase(0,5);
	    check=0;i=0;j=0;k=0;
	    for(p=0;p<20;p++)
	    {
		ip[p]='\0';
		server_name[p]='\0';
		map_type[p]='\0';
	    }
	    for(p=5;p<recvlen;p++)
	    {
		if(response[p]==0)
		{
			check++;
		
	//		cout<<response[p]<<"\n";
		}
		else
		{
			
			switch(check)
			{
				case 0:
				{
				        ip[i++]=response[p];
					break;
				}
				case 1:
				{
					server_name[k++]=response[p];
					break;
				}
				case 2:
				{
					map_type[j++]=response[p];
					break;
				}
				default:
				{
					break;
				}	
			}
		  }
	    }
	    GtkTreeStore *iplist;
  	    GtkTreeIter *iter;
	//    GtkWidget *treeview1= lookup_widget(button, "treeview1");
  	    iplist = gtk_tree_store_new (1, G_TYPE_STRING);

  	    
 	     gtk_tree_store_insert_with_values (iplist, iter, NULL, 0, 0, ip, -1);
	    treeview1 = gtk_tree_view_new_with_model (GTK_TREE_MODEL(iplist));
	    gtk_widget_show (treeview1);
 	    gtk_paned_pack1 (GTK_PANED (hpaned2), treeview1, FALSE, TRUE);
  	    gtk_widget_set_size_request (treeview1, 300, 218);
	//    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview1), 0, "iplist",gtk_cell_renderer_text_new (),"text", 0,NULL);
	    printf("%s\n%s\n%s",ip,server_name,map_type);
	/*    for(z=0;z<i;z++)
	    {
		printf("%s",ip);
	    }
	    printf("\n");
	    for(z=0;z<k;z++)
            {
                printf("%s",server_name);
            }
            printf("\n");
	    for(z=0;z<i+1;z++)
            {
                printf("%s",map_type);
            }*/
            printf("\n");
	    
  //	    printf("%s",resp);
	}
    }
/* Execution never reaches here. Program termination is handled by the
alarm_handler function.
*/
    return 0;
}



